package com.smasher.bluetooth.connect;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresPermission;
import androidx.core.content.ContextCompat;

import java.lang.reflect.Method;

public class BaseConnect implements Handler.Callback {

    public static final String TAG = "BaseConnect";

    protected final BluetoothManager bluetoothManager;
    protected final BluetoothAdapter bluetoothAdapter;

    protected Handler mHandler = new Handler(Looper.getMainLooper(), this);

    protected BleConnectionListener connectionListener;

    public BaseConnect(Context context) {
        bluetoothManager = context.getSystemService(BluetoothManager.class);
        //蓝牙适配器
        bluetoothAdapter = bluetoothManager.getAdapter();
    }

    public void init(Context context) {
        //注册广播
        registerStateReceiver(context);
    }

    public void setConnectionListener(BleConnectionListener listener) {
        this.connectionListener = listener;
    }

    private final BroadcastReceiver bluetoothStateReceiver = new BroadcastReceiver() {
        @SuppressLint("MissingPermission")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.e(TAG, "onReceive: " + action);
            if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                switch (state) {
                    case BluetoothAdapter.STATE_ON:
                        Log.i(TAG, "蓝牙已开启");
                        break;
                    case BluetoothAdapter.STATE_OFF:
                        Log.i(TAG, "蓝牙已关闭");
                        break;
                    case BluetoothAdapter.STATE_TURNING_ON:
                        Log.i(TAG, "蓝牙正在开启...");
                        break;
                    case BluetoothAdapter.STATE_TURNING_OFF:
                        Log.i(TAG, "蓝牙正在关闭...");
                        break;
                }
            }

            if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {//连接状态变化
                Log.i(TAG, "onReceive: 连接状态变化");

                int connectState = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.ERROR);
                Log.i(TAG, "onReceive: connectState=" + connectState);

                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                switch (connectState) {
                    case BluetoothAdapter.STATE_CONNECTED:
                        Log.i(TAG, "已连接: ");
                        break;
                    case BluetoothAdapter.STATE_CONNECTING:
                        Log.i(TAG, "正在连接: ");
                        break;
                    case BluetoothAdapter.STATE_DISCONNECTED:
                        Log.i(TAG, "已断开: ");
                        break;
                    case BluetoothAdapter.STATE_DISCONNECTING:
                        Log.i(TAG, "正在断开: ");
                        break;
                    default:
                        Log.i(TAG, "onReceive: 配对状态变化: " + connectState);
                        break;
                }
            }

            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//配对状态变化
                Log.i(TAG, "onReceive: 配对状态变化");
                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
                Log.i(TAG, "onReceive: bondState=" + bondState);
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                switch (bondState) {
                    case BluetoothDevice.BOND_BONDED:
                        Log.i(TAG, "配对成功: ");
                        if (device != null) {
                            // 触发连接
                            Log.i(TAG, "配对设备: " + device.getName());
                            if (connectionListener != null) {
                                connectionListener.onPairingSuccess(device);
                            }
                        }
                        break;
                    case BluetoothDevice.BOND_BONDING:
                        Log.i(TAG, "配对中...");
                        break;
                    case BluetoothDevice.BOND_NONE:
                        Log.i(TAG, "配对已取消");
                        break;
                }
            }

            if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int pairingVariant = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
                int key = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, BluetoothDevice.ERROR);
                Log.i(TAG, "配对模式: " + pairingVariant + " 长度=" + key);
                if (connectionListener != null) {
                    connectionListener.onPairingRequested(device, pairingVariant);
                }
            }
        }
    };


    /**
     * 声明为 RECEIVER_EXPORTED
     * sendBroadcast 必须为 Intent 指定 package
     * 为了兼容未指定 package 的广播 保证能接收到 所以使用 RECEIVER_EXPORTED
     */
    private void registerStateReceiver(Context context) {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);

        ContextCompat.registerReceiver(context, bluetoothStateReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED);
    }

    private void unregisterStateReceiver(Context context) {
        context.unregisterReceiver(bluetoothStateReceiver);
    }


    @RequiresPermission(allOf = {Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_PRIVILEGED})
    private void autoConfirmPairing(BluetoothDevice device, int pairingVariant) {

        if (pairingVariant == BluetoothDevice.PAIRING_VARIANT_PIN) {
            // 自动输入默认 PIN
            try {
                Method method = device.getClass().getMethod("setPin", byte[].class);
                method.invoke(device, "0000".getBytes());
            } catch (Exception e) {
                Log.e(TAG, "设置 PIN 失败: ", e);
            }
        } else if (pairingVariant == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION) {
            // 自动确认 Passkey
            // device.setPairingConfirmation(true);
            try {
                device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
            } catch (Exception e) {
                Log.e(TAG, "自动确认失败", e);
            }
        }
    }


    public void connectDevice(Context context, BluetoothDevice device){

    }


    public void connectDeviceImmediately(Context context, BluetoothDevice device){

    }


    @RequiresPermission(allOf = {Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT})
    protected void pairedDevice(BluetoothDevice device) {
        //已配对的取消配对，配对后自动连接。
        if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
            removeBondDevice(device);//取消配对
            //延时配对
            mHandler.postDelayed(device::createBond, 1000);
        } else if (device.getBondState() == BluetoothDevice.BOND_NONE) {
            device.createBond();//配对
        }
    }


    //解绑设备
    private static boolean removeBondDevice(BluetoothDevice device) {
        boolean state = false;
        try {
            state = (boolean) device.getClass().getMethod("removeBond").invoke(device);
        } catch (Exception e) {
            Log.e(TAG, "removeBondDevice: " + e.getLocalizedMessage());
        }
        return state;
    }



    public void release(Context context) {
        unregisterStateReceiver(context);
        mHandler.removeCallbacksAndMessages(null);
    }

    @Override
    public boolean handleMessage(@NonNull Message msg) {
        return false;
    }
}
